package com.wenlin.myproduction.ui;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.TextView;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.wenlin.myproduction.R;
import com.wenlin.myproduction.base.BaseSwipeActivity;
import com.wenlin.myproduction.bean.NumberCard;
import com.wenlin.myproduction.binder.NumberCardBinder;
import com.wenlin.myproduction.util.Checker;
import com.wenlin.myproduction.util.ToastUtils;
import com.wenlin.myproduction.util.TypeData;
import com.wenlin.myproduction.util.TypeDataNames;
import com.wenlin.myproduction.util.UI;
import com.wenlin.myproduction.util.ValCommon;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import butterknife.BindView;
import butterknife.OnClick;
import me.drakeet.multitype.Items;
import me.drakeet.multitype.MultiTypeAdapter;

/**
 * @author 文琳
 * @time 2020/9/1 13:58
 * @desc 翻牌小游戏
 */
public class FlipCardActivity extends BaseSwipeActivity {
    private static final int ROW_LENGTH = 8;//11
    private static final int COLUMN_LENGTH = 5;//8
    private static final int COUPLE_NUM = ROW_LENGTH * COLUMN_LENGTH / 2;
    @BindView(R.id.tv_num)
    TextView tvNum;
    @BindView(R.id.tv_time)
    TextView tvTime;
    @BindView(R.id.rv)
    RecyclerView rv;
    private Items items = new Items();
    private MultiTypeAdapter adapter;
    private int showTimes;
    private int firstChoosePos;
    private CountDownTimer timer;
    private int leftCouples;
    private int tryTimes;
    private int seconds;
    private boolean locked;
    private String[] words = {"left", "right", "run", "jump", "swim", "play", "stop", "sleep", "eat", "walk",
            "phone", "help", "scan", "watch", "like", "hate", "drink", "think", "thank", "home"};
    private String[] means = {"左", "右", "跑", "跳", "游泳", "玩", "停止", "睡觉", "吃", "走",
            "手机", "帮忙", "浏览", "观看", "喜欢", "讨厌", "喝", "思考", "谢谢", "家"};
    private int firstPos = 0, secondPos = 1;

    public static void start(Activity activity) {
        Intent intent = new Intent(activity, FlipCardActivity.class);
        activity.startActivity(intent);
    }

    @Override
    public int getContentView() {
        return R.layout.activity_flip_card;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle(ValCommon.FLIP_CARD_GAME);
        UI.setText(tvNum, "对子：" + COUPLE_NUM);
        initAdapter();
        resetGame();
    }

    /**
     * 初始化适配器
     */
    private void initAdapter() {
        adapter = new MultiTypeAdapter(items);
        adapter.register(NumberCard.class, new NumberCardBinder());
        rv.setLayoutManager(new GridLayoutManager(this, COLUMN_LENGTH));
        rv.setHasFixedSize(true);
        rv.setAdapter(adapter);
    }

    /**
     * 重置游戏
     */
    private void resetGame() {
        if (Checker.hasList(items)) {
            items.clear();
            adapter.notifyDataSetChanged();
        }
        leftCouples = COUPLE_NUM;
        tryTimes = 0;
        firstChoosePos = -1;
        showTimes = 0;
        //装上数据
        List<NumberCard> list = new ArrayList<>();
        for (int i = 0; i < COUPLE_NUM * 2; i++) {
            int number = i;
            if (number >= COUPLE_NUM) number -= COUPLE_NUM;
            NumberCard numberCard = new NumberCard(number, i >= COUPLE_NUM ? means[number] : words[number]);
            list.add(numberCard);
        }
        //随机打乱
        Random random = new Random();
        for (int i = 0; i < COUPLE_NUM * 2; i++) {
            int changePosition = random.nextInt(list.size());
            NumberCard temp = list.get(changePosition);
            list.set(changePosition, list.get(i));
            list.set(i, temp);
        }
        //设置位置编号
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setPosition(i);
        }
        items.addAll(list);
        adapter.notifyDataSetChanged();
        locked = true;
        //依次展示数字，再依次隐藏
        secondPos = firstPos = -1;
        UI.releaseTimer(timer);
        timer = new CountDownTimer(Integer.MAX_VALUE, 300) {
            @Override
            public void onTick(long millisUntilFinished) {
                boolean hide = secondPos > items.size() - 1;//若显示完毕则开始逐个隐藏
                hideFirstShowSecond(hide ? firstPos : -1, hide ? -1 : secondPos);
                if (hide) firstPos++;
                else secondPos++;
                if (firstPos > items.size() - 1) {
                    timer.cancel();
                    onFinish();
                }
            }

            @Override
            public void onFinish() {
                if (Checker.hasNoList(items)) return;
                for (int i = 0; i < items.size(); i++) {
                    Object o = items.get(i);
                    if (o instanceof NumberCard) {
                        NumberCard nc = (NumberCard) o;
                        if (nc.isShow()) {
                            nc.setShow(false);
                            adapter.notifyItemChanged(i);
                        }
                    }
                }
                UI.releaseTimer(timer);
                locked = false;
                seconds = 0;
                timer = new CountDownTimer(Integer.MAX_VALUE, 1000) {
                    @Override
                    public void onTick(long millisUntilFinished) {
                        UI.setText(tvTime, "时：" + seconds++);
                    }

                    @Override
                    public void onFinish() {
                        //nothing
                    }
                }.start();
            }
        }.start();
    }

    /**
     * 是否是每一次匹配的第一个选中，每次匹配分第一个和第二个
     *
     * @return 所求
     */
    private boolean isFirstChoose() {
        return showTimes % 2 == 1;
    }

    /**
     * 隐藏第一个，显示第二个，负数或者超限时不操作
     *
     * @param firstPosition  第一个位置
     * @param secondPosition 第二个位置
     */
    private void hideFirstShowSecond(int firstPosition, int secondPosition) {
        if (Checker.hasNoList(items)) return;
        if (firstPosition >= 0 && firstPosition < items.size()) {
            Object o1 = items.get(firstPosition);
            if (o1 instanceof NumberCard) {
                NumberCard nc1 = (NumberCard) o1;
                nc1.setShow(false);
                adapter.notifyItemChanged(firstPosition);
            }
        }
        if (secondPosition >= 0 && secondPosition < items.size()) {
            Object o2 = items.get(secondPosition);
            if (o2 instanceof NumberCard) {
                NumberCard nc2 = (NumberCard) o2;
                nc2.setShow(true);
                adapter.notifyItemChanged(secondPosition);
            }
        }
    }

    /**
     * 隐藏两个数字
     *
     * @param firstPosition  第一个位置
     * @param secondPosition 第二个位置
     */
    private void hideTwoNumber(int firstPosition, int secondPosition) {
        if (Checker.hasNoList(items)) return;
        Object o1 = items.get(firstPosition);
        if (o1 instanceof NumberCard) {
            NumberCard nc1 = (NumberCard) o1;
            nc1.setShow(false);
            adapter.notifyItemChanged(firstPosition);
        }
        Object o2 = items.get(secondPosition);
        if (o2 instanceof NumberCard) {
            NumberCard nc2 = (NumberCard) o2;
            nc2.setShow(false);
            adapter.notifyItemChanged(secondPosition);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void threadHandle(TypeData typeData) {
        String name = typeData.getName();
        if (name.equals(TypeDataNames.clickNumberCard)) {
            NumberCard numberCard = (NumberCard) typeData.getData();
            if (Checker.isNull(numberCard)) return;
            if (locked) return;//避免还在恢复的时候点击
            if (Checker.hasNoList(items)) return;
            for (int i = 0; i < items.size(); i++) {
                Object o = items.get(i);
                if (o instanceof NumberCard) {
                    NumberCard nc = (NumberCard) o;
                    if (nc.getPosition() == numberCard.getPosition() && !nc.isShow()) {
                        nc.setShow(true);
                        showTimes++;
                        adapter.notifyItemChanged(i);
                        if (isFirstChoose()) {
                            firstChoosePos = nc.getPosition();
                        } else {
                            //检查第一个选中的数字跟第二个是否一样
                            Object oFirst = items.get(firstChoosePos);
                            if (oFirst instanceof NumberCard) {
                                NumberCard ncFirst = (NumberCard) oFirst;
                                if (ncFirst.getNumber() == nc.getNumber()) {//选中了，得分
                                    ncFirst.setFinish(true);
                                    adapter.notifyItemChanged(firstChoosePos);
                                    nc.setFinish(true);
                                    adapter.notifyItemChanged(i);
                                    if (--leftCouples <= 0) {
                                        UI.releaseTimer(timer);
                                        ToastUtils.getInstance().showSuccess("恭喜成功");
                                    }
                                } else {//若两个数字不一样，则一会儿之后自动不再显示
                                    final int secondChoosePos = i;
                                    locked = true;
                                    UI.setText(tvNum, "翻：" + (++tryTimes));
                                    rv.postDelayed(() -> {
                                        hideTwoNumber(firstChoosePos, secondChoosePos);
                                        locked = false;
                                    }, 300);
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        UI.releaseTimer(timer);
    }

    @OnClick({R.id.tv_reset})
    void click(View view) {
        switch (view.getId()) {
            case R.id.tv_reset:
                resetGame();
                break;
            default:
        }
    }

}
